package hied.cleaning;

import hied.AvgDev;
import hied.Knowledge;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class CorrectForms {
	private List<CorrectFormInfo> correctFormInfos = new ArrayList<CorrectFormInfo>();
	private List<String> notFound = new ArrayList<String>();
	private static final double FIRST_GAP = 1.5;
	private static final double NEXT_GAPS = 1;
	private String txt;

	public CorrectForms(String[] incorrectWords, Knowledge knowledge) {
		String correct;
		AvgDev avgDev;
		for (String word : incorrectWords) {
			correct = knowledge.getCorrectForm(word);
			if (correct == null) {
				this.notFound.add(word);
			} else {
				avgDev = knowledge.getWordPosition(correct,
						incorrectWords.length);
				this.correctFormInfos.add(new CorrectFormInfo(correct, avgDev
						.getAverage(), avgDev.getStDev()));
			}
		}
		Collections.sort(this.correctFormInfos);
	}

	public String rebuild() {
		if (this.txt == null) {
			synchronized (this) {
				if (this.txt == null) {
					StringBuilder sb = new StringBuilder();
					double lastPosition = 0;
					int gaps;
					for (CorrectFormInfo cfi : this.correctFormInfos) {
						gaps = this.calculateGapNaumber(lastPosition, cfi
								.getAvg());
						for (int i = 0; i < gaps; i++) {
							if (this.notFound.size() > 0) {
								sb.append(this.notFound.remove(0));
								sb.append(" ");
							}
						}
						sb.append(cfi.getForm());
						sb.append(" ");
						lastPosition = cfi.getAvg();
					}
					for (String s : notFound) {
						sb.append(s);
						sb.append(" ");
					}
					this.txt = sb.toString().trim();
				}
			}
		}
		return this.txt;
	}

	private int calculateGapNaumber(double distance) {
		if (distance < FIRST_GAP) {
			return 0;
		} else {
			return 1 + (int) ((distance - FIRST_GAP) / NEXT_GAPS);
		}
	}

	private int calculateGapNaumber(double from, double to) {
		return this.calculateGapNaumber(to - from);
	}
}
